package actions;

import actions.combat.CombatThread;
import bin.Mud;
import exceptions.MudExceptions;
import items.consumables.Consumable;
import players.Player;
import rooms.southPod.OremLobby;

public class ActionDecider {
    private Mud mudWindow;
    private CombatThread combatThread = null;

    public ActionDecider(Mud mudWindow) {
        this.mudWindow = mudWindow;
    }

    public void doAction() {
        DirectionDecider directionDecider = new DirectionDecider(mudWindow);
        if (directionDecider.getDirection() != null) {
            if (combatThread == null || !combatThread.isAlive()) {
                directionDecider.getDirection();
                directionDecider.moveDirection();
                return;
            } else throw MudExceptions.inCombat();

        }
        
        HelpDecider helpDecider = new HelpDecider(mudWindow);
        if (helpDecider.isHelp()) {
            helpDecider.showHelp();
            return;
        }

        GetDecider getDecider = new GetDecider(mudWindow);
        if (getDecider.isGet()) {
            if (getDecider.isValidGet()) {
                mudWindow.setReturnText("You got the " + getDecider.itemToGet().getTitle());
                getDecider.pickUpItem();
                return;
            } else {
                throw MudExceptions.invalidGet();
            }
        }
        if (getDecider.isDrop()) {
            if (getDecider.isValidDrop()) {
                mudWindow.setReturnText("You dropped your " + getDecider.dropItem() + ".");
                getDecider.dropItem();
                return;
            } else {
                throw MudExceptions.invalidDrop();
            }
        }

        InventoryDecider inventoryDecider = new InventoryDecider(mudWindow);
        if (inventoryDecider.isInventory()) {
            inventoryDecider.showInventory();
            return;
        }

        EquipDecider equipDecider = new EquipDecider(mudWindow);
        Player player = mudWindow.getPlayer();

        if (equipDecider.isShowEquip()) {
            player.showEquipment();
            return;
        } else if (equipDecider.isEquip()) {
            if (equipDecider.itemToEquip() != null) {
                player.equipItem(equipDecider.itemToEquip());
                return;
            } else {
                throw MudExceptions.invalidEquip();
            }

        } else if (equipDecider.isUnequip()) {
            if (equipDecider.itemToUnequip() != null) {
                player.removeItemFromEquipment(equipDecider.itemToUnequip());
                return;
            } else {
                throw MudExceptions.invalidUnequip();
            }
        }

        StatsDecider statsDecider = new StatsDecider(mudWindow);
        if (statsDecider.isStats()) {
            mudWindow.setReturnText("");
            mudWindow.setReturnText(mudWindow.getPlayer().getDescription());
            mudWindow.getPlayer().showStats();
            return;
        }

        LookDecider lookDecider = new LookDecider(mudWindow);
        ContainerDecider lookContainer = new ContainerDecider(mudWindow);
        if (lookDecider.isLook()) {
            if (lookDecider.isLookRoom()) {
                lookDecider.doLookRoom();
                return;
            } else if (lookDecider.isLookContainer() && lookContainer.containerToLook().isOpen()) {
                mudWindow.setReturnText("Items in the " + lookContainer.containerToLook().getTitle() + ":" + lookContainer.containerToLook().showContents());
                return;
            } else if (lookDecider.isLookContainer() && !lookContainer.containerToLook().isOpen()) {
                throw MudExceptions.itemNotOpen();
            } else {
                throw MudExceptions.invalidLook();
            }
        }

        ContainerDecider containerDecider = new ContainerDecider(mudWindow);
        if (containerDecider.isOpen()) {
            if (containerDecider.itemToOpen() != null) {
                mudWindow.setReturnText("You open the " + containerDecider.itemToOpen().getTitle());
                containerDecider.itemToOpen().openContainer();
                return;
            } else {
                throw MudExceptions.invalidOpen();
            }
        }

        UseDecider useDecider = new UseDecider(mudWindow);
        if (useDecider.isUse()) {
            if (useDecider.isValidUse()) {
                mudWindow.setReturnText(((Consumable) useDecider.getItemToUse()).getActionText());
                useDecider.useItem((Consumable) useDecider.getItemToUse());
                return;
            } else throw MudExceptions.invalidUse();
        }

        CheatDecider cheatDecider = new CheatDecider(mudWindow);
        if (cheatDecider.isGodMode() || cheatDecider.isRecall()) {
            if (cheatDecider.isGodMode()) {
                mudWindow.getPlayer().setMaximumHealth(1000000);
                mudWindow.getPlayer().setHealthPoints(1000000);
                return;
            } else if (cheatDecider.isRecall()) {
                mudWindow.setRoom(OremLobby.getInstance());
                return;
            } else throw MudExceptions.invalidCheat();
        }

        CombatDecider combatDecider = new CombatDecider(mudWindow);
        if (combatDecider.isAttack()) {
            if (combatDecider.isValidMob()) {
                if (combatThread == null || !combatThread.inCombat()) {
                    combatThread = new CombatThread(mudWindow, combatDecider.getMobToAttack(), mudWindow.getPlayer());
                    combatThread.start();
                } else {
                    throw MudExceptions.invalidCombat();
                }
                return;
            } else {
                throw MudExceptions.invalidNPC();
            }
        }
        if (combatDecider.isFlee()) {
            if (combatThread != null && combatThread.inCombat()) {
                if (combatThread.isAlive() && combatThread.fleeSuccess()) {
                    combatThread.setFlee();
                    return;
                } else {
                    throw MudExceptions.invalidFlee();
                }
            } else {
                throw MudExceptions.notInCombat();
            }

        }
        throw MudExceptions.invalidCommand();
    }
}